package com.wdciti.sccp.iot.gateway.endpoint.my;

import com.alibaba.fastjson.JSON;
import com.wdciti.sccp.iot.gateway.domain.Channel;
import com.wdciti.sccp.iot.gateway.domain.PersonTagBind;
import com.wdciti.sccp.iot.gateway.domain.TagPosition;
import com.wdciti.sccp.iot.springvertx.annotation.VerticleBean;
import io.netty.handler.codec.mqtt.MqttQoS;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.shareddata.LocalMap;
import io.vertx.mqtt.MqttClient;
import io.vertx.mqtt.MqttClientOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author JINWEN
 * 连时序库，写代码读库，然后回写数据库。
 */
@Slf4j
@VerticleBean(isWorker = false)
public class IntegratingPositionDataVerticle extends AbstractVerticle {

    @Value("${iotdb.host}")
    private String mqttIp;

    @Value("${iotdb.mqtt.port}")
    private Integer mqttPort;

    @Value("${iotdb.username}")
    private String mqttUserName;

    @Value("${iotdb.password}")
    private String mqttPassWord;

    @Override
    public void start() {

        MqttClientOptions options = new MqttClientOptions().setUsername(mqttUserName).setPassword(mqttPassWord);
        MqttClient client = MqttClient.create(vertx, options).connect(mqttPort, mqttIp,
                res -> System.out.println("iotdb::mqtt connected! " + res.succeeded()));

        LocalMap<String, JsonObject> personTagCache = vertx.sharedData().getLocalMap("personTagList");
//        LocalMap<String,JsonObject> mexNow = vertx.sharedData().getLocalMap(Channel.mex.name()+"_now");

        vertx.setPeriodic(2000, 5000, hd -> {
            if (personTagCache.isEmpty()) {
                return;
            }
            personTagCache.keySet().forEach(personId -> {
                Map<String, Object> binds = personTagCache.getOrDefault(personId, JsonObject.of()).getMap();
                Map<String, TagPosition> lastMap = new HashMap<>();
                binds.forEach((k, v) -> {
                    PersonTagBind bind = ((JsonObject) v).mapTo(PersonTagBind.class);
                    LocalMap<String, JsonObject> lastCache = vertx.sharedData().getLocalMap(bind.getChannel() + "_now");
                    //log.info("+++++++++++lastCache({}) size :{}",bind.getChannel(),lastCache.size());
                    //log.info("lastCache:【{}】,value：{}",bind.getChannel(), JSON.toJSONString(lastCache));
                    JsonObject lastJson = lastCache.get(bind.getPersonId());
                    if (lastJson != null && !lastJson.isEmpty()) {
                        //log.info("+++++++++++lastCache({}) personId:{}",bind.getChannel(),bind.getPersonId());
                        TagPosition last = lastJson.mapTo(TagPosition.class);
                        lastMap.put(last.getChannel(), last);
                        //log.info("lastMap:{}",JSON.toJSONString(lastMap));
                    }
                });
                //log.info("++++++++++lastMap size={}",lastMap.size());
                TagPosition p = chooseAtBusiness(lastMap);
                if (p != null) {
                    //log.info("++++++p={}",p.getTagId());
                    JsonObject sendObj = revertObj(p);
                    client.publish(sendObj.getString("device"), sendObj.toBuffer(), MqttQoS.AT_LEAST_ONCE, false, false);
                }
            });
        });
    }

    private TagPosition chooseAtBusiness(Map<String, TagPosition> lastMap) {
        //log.info("----进入chooseAtBusiness方法----");
        if (lastMap == null || lastMap.isEmpty()) {
            return null;
        }
//        log.info("----lastMap.values()：{}----",JSON.toJSONString(lastMap.values()));
        ArrayList<String> timeout = new ArrayList<>();
        for (TagPosition tagPosition : lastMap.values()) {
            long abs = Math.abs(System.currentTimeMillis() - tagPosition.getTimestamp());
            if(abs >= 1000 * 60){
                timeout.add(tagPosition.getChannel());
            }
        }

        if (lastMap.isEmpty()) {
            return null;
        } else if (lastMap.containsKey(Channel.pib.name())&&!timeout.contains(Channel.pib.name())) {
            //log.info("@@@chooseAt pib数据：{}",JSON.toJSONString(lastMap.get(Channel.pib.name())));
            return lastMap.get(Channel.pib.name());
        } else if (lastMap.containsKey(Channel.mex.name())&&!timeout.contains(Channel.mex.name())) {
            //log.info("@@@chooseAt mex数据：{}",JSON.toJSONString(lastMap.get(Channel.mex.name())));
            return lastMap.get(Channel.mex.name());
        }else {
            return null;
        }
    }

    private JsonObject revertObj(TagPosition input) {
        // 这里的ID已经换过了。
        String device = "root.position.plat.p_" + input.getTagId();
        return JsonObject.of().put("device", device)
                .put("timestamp", input.getTimestamp())
                .put("measurements", new JsonArray()
                        .add(0, "longitude")
                        .add(1, "latitude")
                        .add(2, "high")
                        .add(3, "channel"))
                .put("values", new JsonArray()
                        .add(0, input.getLongitude())
                        .add(1, input.getLatitude())
                        .add(2, input.getHigh())
                        .add(3, input.getChannel())
                );


    }

}


